#include "menuwidget.h"
#include "ui_menuwidget.h"

MenuWidget::MenuWidget(QWidget *parent) :
    QDockWidget(parent),
    ui(new Ui::MenuWidget)
{
    ui->setupUi(this);
    ui->tabWidget->setAcceptDrops(true);
    this->setAcceptDrops(true);
    connect(&EventCenter::Instance(),&EventCenter::ChangeCurNode,this,[=](){
        LoadcurNode();
    });
    InitData();
    InitTabBtns();
    InitSoundChecks();
    InitDataBtns();
    InitLinkerWidget();
    LoadcurNode();
    InitEffectUI();
    connect(&EventCenter::Instance(),&EventCenter::DeleteData,[=](QString& s){
        //删除前端item数据
        for (int i = 0;i < ui->listWidget->count();i++) {
            QListWidgetItem* item = ui->listWidget->item(i);
            QWidget* d = ui->listWidget->itemWidget(item);
            MenuDataItem* di = dynamic_cast<MenuDataItem*>(d);
            if(di && di->GetName() == s)
            {
                ui->listWidget->takeItem(i);
                delete item;
                delete di;
                break;
            }
        }
    });
    //删除linker
    connect(ui->deleteLinkerBtn,&QPushButton::clicked,this,[=](){
        int row = ui->linkerList->currentRow();
        if(GameManager::Instance().curNode->RemoveLinkerAt(row))
        {
            QListWidgetItem* item = ui->linkerList->item(row);
            ui->linkerList->takeItem(row);
            delete item;
            emit EventCenter::Instance().Modify();
        }
    });
}

MenuWidget::~MenuWidget()
{
    delete ui;
    delete linkerEditWidget;
    delete searchData;
    delete effectEditWidget;
}

void MenuWidget::dragEnterEvent(QDragEnterEvent *event)
{
    event->acceptProposedAction();
}

void MenuWidget::dropEvent(QDropEvent *event)
{
    switch(ui->tabWidget->currentIndex())
    {
    case 0:
        MusicDropEvent(event);
        break;
    case 1:
        break;
    case 2:
        break;
    case 3:
        break;
    default:
        break;
    }
}

void MenuWidget::MusicDropEvent(QDropEvent *event)
{
    ResourceListWidget * w = dynamic_cast<ResourceListWidget*>(event->source());
    if(!w) return;
    QString path = w->GetCurItemPath();
    QDir d;
    path = d.relativeFilePath(path);
    if(FileManager::Instance().GetFileType(path) != FileManager::SOUND)
        return;
    QString name = QFileInfo(path).fileName();
    emit EventCenter::Instance().Modify();

    if(ui->bgmFrame->geometry().contains(ui->tab->mapFromGlobal(QCursor::pos())))
    {
        ui->bgmBtn->setText(name);
        ui->bgmBtn->setToolTip(path);
        ui->bgmCheck->setChecked(true);
        BGM *b = new BGM(path,ui->bgmLoopCheck->isChecked());
        GameManager::Instance().curNode->stopBgm = ui->bgmStopCheck->isChecked();
        GameManager::Instance().curNode->bgm = b;
    }
    else if(ui->bgseFrame->geometry().contains(ui->tab->mapFromGlobal(QCursor::pos())))
    {
        ui->bgseBtn->setText(name);
        ui->bgseBtn->setToolTip(path);
        ui->bgseCheck->setChecked(true);
        BGM *b = new BGM(path,ui->bgseLoopCheck->isChecked());
        GameManager::Instance().curNode->stopBgse = ui->bgseStopCheck->isChecked();
        GameManager::Instance().curNode->bgse = b;
    }
    else if(ui->soundFrame->geometry().contains(ui->tab->mapFromGlobal(QCursor::pos())))
    {
        ui->soundBtn->setText(name);
        ui->soundBtn->setToolTip(path);
        ui->soundCheck->setChecked(true);
        GameManager::Instance().curNode->soundPath = path;
    }
    emit EventCenter::Instance().RefreshCurNodeItem();
}

void MenuWidget::InitTabBtns()
{
    this->setWidget(ui->tabWidget);
    ui->tabWidget->setTabIcon(0,QIcon(":/res/icon/soundIcon.png"));
    ui->tabWidget->setTabIcon(1,QIcon(":/res/icon/dataIcon.png"));
    ui->tabWidget->setTabIcon(2,QIcon(":/res/icon/effectIcon.png"));
    ui->tabWidget->setTabIcon(3,QIcon(":/res/icon/conditionIcon.png"));
}

void MenuWidget::InitSoundChecks()
{
    QString s = "拖入文件到此处";
    connect(ui->bgmLoopCheck,&QCheckBox::stateChanged,[=](int state)
    {
        if(!GameManager::Instance().curNode->bgm) return;
        if(state == Qt::Unchecked)
        {
            GameManager::Instance().curNode->bgm->loop = false;
        }else if(state == Qt::Checked)
        {
            GameManager::Instance().curNode->bgm->loop = true;
        }
        emit EventCenter::Instance().Modify();
        emit EventCenter::Instance().RefreshCurNodeItem();
    });
    connect(ui->bgmStopCheck,&QCheckBox::stateChanged,[=](int state)
    {
        if(state == Qt::Unchecked)
        {
            GameManager::Instance().curNode->stopBgm = false;
            ui->bgmCheck->setCheckable(true);
        }else if(state == Qt::Checked)
        {
            GameManager::Instance().curNode->stopBgm = true;
            GameManager::Instance().curNode->bgm = nullptr;
            ui->bgmCheck->setChecked(false);
            ui->bgmCheck->setCheckable(false);
            ui->bgmLoopCheck->setChecked(false);
            ui->bgmLoopCheck->setCheckable(false);
            ui->bgmBtn->setText(s);
            ui->bgmBtn->setToolTip(s);
        }
        emit EventCenter::Instance().Modify();
        emit EventCenter::Instance().RefreshCurNodeItem();
    });
    connect(ui->bgmCheck,&QCheckBox::stateChanged,[=](int state){
        if(state == Qt::Unchecked)
        {
            GameManager::Instance().curNode->bgm = nullptr;
            ui->bgmLoopCheck->setCheckable(false);
            ui->bgmLoopCheck->setChecked(false);
            ui->bgmStopCheck->setCheckable(true);
            ui->bgmBtn->setText(s);
            ui->bgmBtn->setToolTip(s);
        }
        else if(state == Qt::Checked)
        {
            ui->bgmLoopCheck->setCheckable(true);
            ui->bgmStopCheck->setCheckable(false);
        }
        emit EventCenter::Instance().Modify();
        emit EventCenter::Instance().RefreshCurNodeItem();
    });
    //bgse
    connect(ui->bgseLoopCheck,&QCheckBox::stateChanged,[=](int state)
    {
        if(!GameManager::Instance().curNode->bgse) return;
        if(state == Qt::Unchecked)
        {
            GameManager::Instance().curNode->bgse->loop = false;
        }else if(state == Qt::Checked)
        {
            GameManager::Instance().curNode->bgse->loop = true;
        }
        emit EventCenter::Instance().Modify();
        emit EventCenter::Instance().RefreshCurNodeItem();
    });
    connect(ui->bgseStopCheck,&QCheckBox::stateChanged,[=](int state)
    {
        if(state == Qt::Unchecked)
        {
            GameManager::Instance().curNode->stopBgse = false;
            ui->bgseCheck->setCheckable(true);
        }else if(state == Qt::Checked)
        {
            GameManager::Instance().curNode->stopBgse = true;
            GameManager::Instance().curNode->bgse = nullptr;
            ui->bgseCheck->setChecked(false);
            ui->bgseCheck->setCheckable(false);
            ui->bgseLoopCheck->setChecked(false);
            ui->bgseLoopCheck->setCheckable(false);
            ui->bgseBtn->setText(s);
            ui->bgseBtn->setToolTip(s);
        }
        emit EventCenter::Instance().Modify();
        emit EventCenter::Instance().RefreshCurNodeItem();
    });
    connect(ui->bgseCheck,&QCheckBox::stateChanged,[=](int state){
        if(state == Qt::Unchecked)
        {
            GameManager::Instance().curNode->bgse = nullptr;
            ui->bgseLoopCheck->setCheckable(false);
            ui->bgseLoopCheck->setChecked(false);
            ui->bgseStopCheck->setCheckable(true);
            ui->bgseBtn->setText(s);
            ui->bgseBtn->setToolTip(s);
        }
        else if(state == Qt::Checked)
        {
            ui->bgseLoopCheck->setCheckable(true);
            ui->bgseStopCheck->setCheckable(false);
        }
        emit EventCenter::Instance().Modify();
        emit EventCenter::Instance().RefreshCurNodeItem();
    });
    //sound
    connect(ui->soundCheck,&QCheckBox::stateChanged,[=](int state){
        if(state == Qt::Unchecked)
        {
            GameManager::Instance().curNode->soundPath = "";
            ui->soundBtn->setText(s);
            ui->soundBtn->setToolTip(s);
        }
        emit EventCenter::Instance().Modify();
        emit EventCenter::Instance().RefreshCurNodeItem();
    });
}

void MenuWidget::InitDataBtns()
{
    connect(ui->intBtn,&QPushButton::clicked,this,[=](){
        AddDataItem(_INT);
    });
    connect(ui->boolBtn,&QPushButton::clicked,this,[=](){
        AddDataItem(_BOOL);
    });
    connect(ui->textBtn,&QPushButton::clicked,this,[=](){
        AddDataItem(_STRING);
    });
    connect(ui->floatBtn,&QPushButton::clicked,this,[=](){
        AddDataItem(_FLOAT);
    });
    searchData = new SearchLineEdit(this,GameData::Instance().GetDataListModel());
    ui->dataHorizontalLayout->addWidget(searchData);
    connect(ui->SearchBtn,&QPushButton::clicked,this,[=](){
        for(int i = 0;i < ui->listWidget->count();i++)
        {
            QListWidgetItem* item = ui->listWidget->item(i);
            QWidget* w = ui->listWidget->itemWidget(item);
            MenuDataItem* mi = dynamic_cast<MenuDataItem*>(w);
            if(mi && mi->GetName() == searchData->text())
            {
                ui->listWidget->setCurrentRow(i);
                break;
            }
        }
    });
}

void MenuWidget::InitEffectUI()
{
    //打开特效编辑界面
    effectEditWidget = new EffectEditWidget();
    connect(ui->EditEffectBtn,&QPushButton::clicked,[=](){
        effectEditWidget->show();
    });
    connect(ui->effectRadioButton,&QRadioButton::toggled,[=](bool check){
        if(effectEditWidget)
        {
            QString name = check?ui->EffectComboBox->currentText() : "";
            effectEditWidget->SendInfo(name);
        }
    });
    connect(ui->EffectComboBox,&QComboBox::currentTextChanged,[=](){
        if(effectEditWidget && ui->effectRadioButton->isChecked())
            effectEditWidget->SendInfo(ui->EffectComboBox->currentText());
    });
    connect(&EventCenter::Instance(),&EventCenter::AddEffect,[=](QString name){
        ui->EffectComboBox->addItem(name);
    });
    connect(&EventCenter::Instance(),&EventCenter::DeleteEffect,[=](QString name){
        for(int i = 0;i < ui->EffectComboBox->count();i++)
        {
            if(ui->EffectComboBox->itemText(i) == name)
            {
                ui->EffectComboBox->removeItem(i);
                break;
            }
        }
    });
    connect(&EventCenter::Instance(),&EventCenter::GetParticleInfo,this,[=](){
        if(!effectEditWidget)
            effectEditWidget = new EffectEditWidget();
        effectEditWidget->SendInfo(GameManager::Instance().curNode->effectName);
    });
    //渐暗过渡
    connect(ui->blackCheckBox,&QCheckBox::toggled,[=](bool toggle){
        GameManager::Instance().curNode->black = toggle;
        emit EventCenter::Instance().Modify();
    });
    void (QSpinBox:: *spinBoxSignal)(int) = &QSpinBox::valueChanged;
    connect(ui->blackTimeSpinBox,spinBoxSignal,this,[=](int v){
        GameManager::Instance().curNode->blackTime = v;
        emit EventCenter::Instance().Modify();
    });
}

void MenuWidget::InitData()
{
    connect(&EventCenter::Instance(),&EventCenter::Save,this,[=](){
        FileManager::Instance().SaveData();
    });
    //读数据
    JsonTranslator jt;
    QJsonObject* ob = FileManager::Instance().ReadJsonFile(FileManager::Instance().gameDataPath);
    if(ob)
        jt.ReadData(ob);
    //添加到前端
    RefreshData();
    connect(&EventCenter::Instance(),&EventCenter::RefreshData,[=](){RefreshData();});
}

void MenuWidget::RefreshData()
{
    //清理内存
    for(int i = 0;i < ui->listWidget->count();i++)
    {
        QWidget* w = ui->listWidget->itemWidget(ui->listWidget->item(i));
        if(w)
        {
            ui->listWidget->removeItemWidget(ui->listWidget->item(i));
            delete w;
        }
    }
    ui->listWidget->clear();
    //string
    for(auto it = GameData::Instance().stringData.begin();it != GameData::Instance().stringData.end();it++)
    {
        QListWidgetItem* i = new QListWidgetItem();
        MenuDataItem* m = new MenuDataItem(_STRING);
        i->setSizeHint(QSize(300,100));
        ui->listWidget->addItem(i);
        ui->listWidget->setItemWidget(i,m);
        m->SetName(it.key());
        m->ShowValue(it.key());
    }
    //int
    for(auto it = GameData::Instance().intData.begin();it != GameData::Instance().intData.end();it++)
    {
        QListWidgetItem* i = new QListWidgetItem();
        MenuDataItem* m = new MenuDataItem(_INT);
        i->setSizeHint(QSize(300,100));
        ui->listWidget->addItem(i);
        ui->listWidget->setItemWidget(i,m);
        m->SetName(it.key());
        m->ShowValue(it.key());
    }
    //float
    for(auto it = GameData::Instance().floatData.begin();it != GameData::Instance().floatData.end();it++)
    {
        QListWidgetItem* i = new QListWidgetItem();
        MenuDataItem* m = new MenuDataItem(_FLOAT);
        i->setSizeHint(QSize(300,100));
        ui->listWidget->addItem(i);
        ui->listWidget->setItemWidget(i,m);
        m->SetName(it.key());
        m->ShowValue(it.key());
    }
    //bool
    for(auto it = GameData::Instance().boolData.begin();it != GameData::Instance().boolData.end();it++)
    {
        QListWidgetItem* i = new QListWidgetItem();
        MenuDataItem* m = new MenuDataItem(_BOOL);
        i->setSizeHint(QSize(300,100));
        ui->listWidget->addItem(i);
        ui->listWidget->setItemWidget(i,m);
        m->SetName(it.key());
        m->ShowValue(it.key());
    }
}

void MenuWidget::AddDataItem(DataType t)
{
    QListWidgetItem* i = new QListWidgetItem();
    MenuDataItem* m = new MenuDataItem(t);
    QString s = "我的数据" + QString::number(curDataId);
    m->SetName(s);
    curDataId++;
    i->setSizeHint(QSize(300,100));
    ui->listWidget->addItem(i);
    ui->listWidget->setItemWidget(i,m);
    emit EventCenter::Instance().Modify();
    QString str = "";
    switch(t)
    {
    case _INT:
        GameData::Instance().AddData(s,0);
        break;
    case _STRING:
        GameData::Instance().AddData(s,str);
        break;
    case _BOOL:
        GameData::Instance().AddData(s,false);
        break;
    case _FLOAT:
        GameData::Instance().AddData(s,0.0f);
        break;
    default:break;
    }
}

void MenuWidget::LoadcurNode()
{
   LoadCurNodeSound();
   ClearLinkers();
   LoadCurNodeLinkers();
   LoadCurNodeEffect();
}

void MenuWidget::LoadCurNodeSound()
{
    NarrationNode* n = GameManager::Instance().curNode;
    QString s = "拖入文件到此处";
    ui->bgmStopCheck->setChecked(false);
    ui->bgseStopCheck->setChecked(false);
    //bgm
    if(!n->bgm || n->stopBgm || n->bgm->path.isEmpty())
    {
        ui->bgmBtn->setText(s);
        ui->bgmBtn->setToolTip(s);
        ui->bgmCheck->setChecked(false);
        ui->bgmLoopCheck->setChecked(false);
        if(n->stopBgm)
            ui->bgmStopCheck->setChecked(true);
    }
    else
    {
        QString name = QFileInfo(n->bgm->path).fileName();
        ui->bgmBtn->setText(name);
        ui->bgmBtn->setToolTip(name);
        ui->bgmCheck->setChecked(true);
        ui->bgmLoopCheck->setChecked(n->bgm->loop);
    }
    //bgse
    if(!n->bgse || n->stopBgse || n->bgse->path.isEmpty())
    {
        ui->bgseBtn->setText(s);
        ui->bgseBtn->setToolTip(s);
        ui->bgseCheck->setChecked(false);
        ui->bgseLoopCheck->setChecked(false);
        if(n->stopBgse)
            ui->bgseStopCheck->setChecked(true);
    }
    else
    {
        QString name = QFileInfo(n->bgse->path).fileName();
        ui->bgseBtn->setText(name);
        ui->bgseBtn->setToolTip(name);
        ui->bgseCheck->setChecked(true);
        ui->bgseLoopCheck->setChecked(n->bgse->loop);
    }
    //sound
    if(n->soundPath.count() > 4)
    {
        QString name = QFileInfo(n->soundPath).fileName();
        ui->soundBtn->setText(name);
        ui->soundBtn->setToolTip(name);
        ui->soundCheck->setChecked(true);
    }
    else
    {
        ui->soundBtn->setText(s);
        ui->soundBtn->setToolTip(s);
        ui->soundCheck->setChecked(false);
    }
}

void MenuWidget::LoadCurNodeLinkers()
{
    NarrationNode* n = GameManager::Instance().curNode;
    for (int i = 0;i < n->linkers.count();i++) {
        QListWidgetItem* item = new QListWidgetItem();
        item->setText(n->linkers.at(i)->name);
        ui->linkerList->addItem(item);
    }
}

void MenuWidget::LoadCurNodeEffect()
{
    NarrationNode* n = GameManager::Instance().curNode;
    ui->effectRadioButton->setChecked(n->effect);
    ui->EffectComboBox->setCurrentText(n->effectName);

    ui->blackCheckBox->setChecked(n->black);
    ui->blackTimeSpinBox->setValue(n->blackTime);
}

void MenuWidget::InitLinkerWidget()
{
    linkerEditWidget = new LinkerEditWidget();
    connect(ui->linkerBtn,&QPushButton::clicked,this,[=](){
        QListWidgetItem* item = new QListWidgetItem();
        item->setText("映射器");
        ui->linkerList->addItem(item);
        Linker* linker = new Linker();
        GameManager::Instance().curNode->linkers.push_back(linker);
    });
    connect(ui->linkerList,&QListWidget::itemDoubleClicked,this,[=](QListWidgetItem* i){
        linkerEditWidget->SetName(i->text());
        linkerEditWidget->curRow = ui->linkerList->currentRow();
        linkerEditWidget->ReadNodeLinker();
        linkerEditWidget->show();
    });
    connect(&EventCenter::Instance(),&EventCenter::LinkerEditFinish,[=](){
        int curRow = ui->linkerList->currentRow();
        ui->linkerList->currentItem()->setText(GameManager::Instance().curNode->linkers[curRow]->name);
    });
}

void MenuWidget::ClearLinkers()
{
    for (int i = 0;i < ui->linkerList->count();i++) {
        QWidget* w = ui->linkerList->itemWidget(ui->linkerList->item(i));
        ui->listWidget->removeItemWidget(ui->linkerList->item(i));
        delete w;
    }
    ui->linkerList->clear();
}
